home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / dev / lang / SmallEiffel.lha / SmallEiffel / lib_std / fixed_array2.e < prev    next >
Text File  |  1998-12-22  |  8KB  |  355 lines

  1. -- This file is  free  software, which  comes  along  with  SmallEiffel. This
  2. -- software  is  distributed  in the hope that it will be useful, but WITHOUT 
  3. -- ANY  WARRANTY;  without  even  the  implied warranty of MERCHANTABILITY or
  4. -- FITNESS  FOR A PARTICULAR PURPOSE. You can modify it as you want, provided
  5. -- this header is kept unaltered, and a notification of the changes is added.
  6. -- You  are  allowed  to  redistribute  it and sell it, alone or as a part of 
  7. -- another product.
  8. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  9. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  10. --                       http://www.loria.fr/SmallEiffel
  11. --
  12. class FIXED_ARRAY2[E]
  13.    --   
  14.    -- Resizable two dimensional array.
  15.    -- Unlike ARRAY2, the `lower1' bound and the `lower2' bound are 
  16.    -- frozen to 0. Thus, one can expect better performances.
  17.    --
  18.    
  19. inherit COLLECTION2[E];
  20.    
  21. creation
  22.    make, copy, from_collection2, from_collection, from_model
  23.    
  24. feature
  25.    
  26.    upper1, count1, upper2, count2, count: INTEGER;
  27.    
  28. feature {FIXED_ARRAY2}
  29.    
  30.    storage: NATIVE_ARRAY[E];
  31.    
  32.    capacity : INTEGER; -- of `storage'.
  33.  
  34. feature
  35.    
  36.    lower1: INTEGER is 0;      
  37.  
  38.    lower2: INTEGER is 0;      
  39.    
  40. feature
  41.    
  42.    make(new_count1 , new_count2 : INTEGER) is
  43.      -- Create or reset Current with new dimensions.
  44.      -- All elements are set to the default value of type E.
  45.       require
  46.      new_count1 > 0;
  47.      new_count2 > 0
  48.       do
  49.      count1 := new_count1;
  50.      upper1 := new_count1 - 1;
  51.      count2 := new_count2;
  52.      upper2 := new_count2 - 1;     
  53.      count := count1 * count2;
  54.      if capacity < count then
  55.         capacity := count;
  56.         storage := storage.calloc(capacity);
  57.      else
  58.         storage.clear_all(capacity - 1);
  59.      end;
  60.       ensure
  61.      count1 = new_count1;
  62.      count2 = new_count2;
  63.      all_cleared
  64.       end;
  65.    
  66.    from_collection(model: COLLECTION2[like item]) is
  67.      -- Uses the `model' to update Current.
  68.       local
  69.      i, j: INTEGER;
  70.       do
  71.      make(model.upper1+1, model.upper2+1);
  72.      from
  73.         i := 0;
  74.      until
  75.         i > upper1
  76.      loop
  77.         from
  78.            j := 0;
  79.         until
  80.            j > upper2
  81.         loop
  82.            put(model.item(i,j),i,j);
  83.            j := j + 1;
  84.         end
  85.         i := i + 1;
  86.      end
  87.       end;
  88.  
  89. feature -- Implementation of others feature from COLLECTION2 :
  90.  
  91.    item(line, column: INTEGER): E is
  92.       do
  93.      Result := storage.item(line * count2 + column);
  94.       end;
  95.    
  96.    put(x: like item; line, column: INTEGER) is
  97.       require
  98.      valid_index(line,column)
  99.       do
  100.      storage.put(x,line * count2 + column);     
  101.       end;
  102.    
  103.    force(element: like item; line , column : INTEGER) is
  104.       do
  105.      if not valid_index(line, column) then
  106.         resize(line.max(upper1),column.max(upper2));
  107.      end;
  108.          put(element,line,column);
  109.       end;
  110.  
  111.    copy(other: like Current) is
  112.       do
  113.      count1 := other.count1;
  114.      upper1 := count1 - 1;
  115.      count2 := other.count2;
  116.      upper2 := count2 - 1;
  117.      count := count1 * count2;
  118.      if capacity < count then
  119.         capacity := count;
  120.         storage := storage.calloc(capacity);
  121.      end;
  122.      storage.copy_from(other.storage, count - 1);
  123.       end;
  124.    
  125.    is_equal(other: like Current): BOOLEAN is
  126.       do
  127.      if other = Current then
  128.         Result := true;
  129.      elseif upper1 /= other.upper1 then
  130.      elseif upper2 /= other.upper2 then
  131.      else
  132.         Result := storage.memcmp(other.storage,count);
  133.      end;
  134.       end;
  135.  
  136. feature -- Writing :
  137.    
  138.    set_all_with(x: E) is
  139.      --  All element are set with the value x.
  140.       do
  141.      storage.set_all_with(x,count - 1)
  142.       ensure
  143.          count = old count
  144.       end; -- set_all_with
  145.  
  146.    all_cleared : BOOLEAN is
  147.       do
  148.      result := storage.all_cleared(count - 1);
  149.       end;
  150.    
  151.    slice(l1,up1,l2,up2: INTEGER): like Current is
  152.      -- Create a new collection initialized with elements of
  153.      -- range `low'..`up'. Result has the same dynamic type 
  154.      -- as Current collection.
  155.       local
  156.      ligne,colonne : INTEGER;
  157.      k : INTEGER;
  158.       do
  159.      from 
  160.         !!Result.make((up1 - l1) + 1,(up2 - l2) + 1);
  161.         ligne := l1;
  162.      until 
  163.         ligne > up1
  164.      loop 
  165.         from 
  166.            colonne := l2;
  167.         until 
  168.            colonne > up2
  169.         loop 
  170.            Result.put(item(ligne,colonne),ligne - l1,colonne - l2);
  171.            colonne := colonne + 1;
  172.         end; 
  173.         ligne := ligne + 1;
  174.      end; 
  175.       end; -- slice
  176.    
  177.    set_slice(element: like item;  l1,up1,l2,up2: INTEGER) is
  178.     -- Set all the elements in the 
  179.     -- range [(l1,up1),(l2,up2)] of
  180.     -- Current with the element 'element'.
  181.  
  182.       local
  183.      i,j : INTEGER;
  184.       do
  185.      from 
  186.         i := l1 * count2;
  187.          until 
  188.             i > up1 * count2
  189.          loop 
  190.             from 
  191.                j := l2;
  192.             until 
  193.                j > up2
  194.             loop 
  195.                storage.put(element,i + j);
  196.                j := j + 1;
  197.             end; 
  198.             i := i + count2;
  199.          end; 
  200.       end;
  201.  
  202.    swap(line1, column1, line2, column2 : INTEGER) is
  203.       local
  204.      tmp: like item;
  205.      c2, index1, index2 : INTEGER
  206.       do
  207.      c2 := count2;
  208.      index1 := line1 * c2 + column1;
  209.      index2 := line2 * c2 + column2;     
  210.      tmp := storage.item( index1);     
  211.      storage.put(storage.item(index2) ,index1);
  212.      storage.put(tmp,index2);
  213.       end
  214.    
  215. feature -- Looking and comparison :
  216.  
  217.    nb_occurrences(elt: E): INTEGER is
  218.      -- Number of occurrences using `equal'.
  219.      -- See also `fast_nb_occurrences' to chose
  220.      -- the apropriate one.
  221.       do
  222.          Result := storage.nb_occurrences(elt,count - 1);
  223.       ensure
  224.      Result >= 0;
  225.       end; -- nb_occurences
  226.       
  227.    fast_nb_occurrences(elt: E): INTEGER is
  228.      -- Number of occurrences using `='.
  229.       do
  230.      Result := storage.fast_nb_occurrences(elt,count - 1);
  231.       ensure
  232.      Result >= 0;
  233.       end; -- fast_nb_occurrences
  234.  
  235. feature -- Resizing :
  236.  
  237.    resize(new_count1 , new_count2: INTEGER) is
  238.       require
  239.      new_count1 > 0;
  240.      new_count2 > 0
  241.       local
  242.      tmp: like Current;
  243.      l, c: INTEGER;
  244.       do
  245.      !!tmp.make(new_count1, new_count2);
  246.      -- It may be possible to avoid this ceation when :
  247.      --    new `capacity' <= old `capacity'
  248.      from
  249.         l := line_maximum;
  250.      until
  251.         l < 0
  252.      loop
  253.         from
  254.            c := column_maximum;
  255.         until
  256.            c < 0
  257.         loop
  258.            if tmp.valid_index(l,c) then
  259.           tmp.put(item(l,c),l,c);
  260.            end;
  261.            c := c - 1;
  262.         end;
  263.         l := l - 1;
  264.      end;
  265.      standard_copy(tmp);
  266.       ensure
  267.      upper1 = new_count1 - 1;
  268.      count1 = new_count1;     
  269.      upper2 = new_count2 - 1;
  270.      count2 = new_count2;
  271.      count = new_count1 * new_count2
  272.       end;
  273.  
  274. feature -- Looking and Searching :
  275.  
  276.    has(x: like item): BOOLEAN is
  277.      -- Look for `x' using `equal' for comparison.      
  278.       do
  279.      Result := storage.index_of(x,count-1) <= (count-1);
  280.       end;  -- has
  281.    
  282.    fast_has(x: like item): BOOLEAN is
  283.      -- Same as `has' but use `=' for comparison      
  284.       do
  285.      Result := storage.fast_index_of(x,count - 1) <= (count - 1);
  286.       end; -- fast_has
  287.  
  288. feature -- Other features :
  289.    
  290.    replace_all(old_value, new_value: like item) is
  291.       do
  292.      storage.replace_all(old_value,new_value,count - 1);
  293.       end;
  294.      
  295.    fast_replace_all(old_value, new_value: like item) is
  296.       do
  297.      storage.fast_replace_all(old_value,new_value,count - 1);
  298.       end;
  299.      
  300.    transpose is
  301.      -- Transpose the Current array
  302.       local
  303.      i,j : INTEGER;
  304.      oldu1 , oldu2 : INTEGER;
  305.       do
  306.      oldu1 := upper1;
  307.      oldu2 := upper2;
  308.      resize(upper2.max(upper1),upper2.max(upper1));
  309.      from  
  310.         i := 0;
  311.      until 
  312.         i > upper1 - 1
  313.      loop
  314.         from  
  315.            j := i + 1;
  316.         until 
  317.            j > upper2
  318.         loop
  319.            swap(i,j,j,i);
  320.            j := j + 1;
  321.         end;
  322.         i := i + 1;
  323.      end;
  324.      resize(oldu2,oldu1);
  325.       end;  -- transpose       
  326.    
  327. feature {COLLECTION2}
  328.  
  329.    same_as(other: COLLECTION2[E]): BOOLEAN is
  330.       do
  331.      Result := other.same_as_fixed_array2(Current);
  332.       end;
  333.  
  334.    same_as_array2(other: ARRAY2[E]): BOOLEAN is
  335.       do
  336.      Result := standard_same_as(other);
  337.       end;
  338.  
  339.    same_as_fixed_array2(other: FIXED_ARRAY2[E]): BOOLEAN is
  340.       do
  341.      Result := standard_same_as(other);
  342.       end;
  343.  
  344. invariant
  345.  
  346.    count1 = upper1 + 1;
  347.    
  348.    count2 = upper2 + 1;
  349.  
  350.    count = count1 * count2;
  351.  
  352.    capacity >= count;
  353.  
  354. end -- FIXED_ARRAY2[E]
  355.